from strategy import *
from plot import ploter
import math
from get_stock import *

# 数据分析及日志模块
def analysis(stock,start,end):
    total_stock_value_list = []
    total_cash_value_list = []
    total_account_value_list = []
    daily_return_list = [0]  # 第一个元素定义为0，是因为第一天没有收益率
    cum_return_list = [0]  # 累计收益率

    tradeday = get_stock().get_trade_dates(start,end)

    length = len(tradeday)
    total_stock_value = [0] * length
    total_cash_value = [0] * length
    total_account_value = [0] * length
    ###处理账户信息

    count = -1
    for i in tradeday:
        count = count + 1
        for j in stock.values():
            stock_value = j.loc[i, "stock"]
            total_stock_value[count] = total_stock_value[count] + stock_value
            total_stock_value[count] = round(total_stock_value[count], 4)  # 股票账户每天的持仓

            cash_value = j.loc[i, "cash"]
            total_cash_value[count] = total_cash_value[count] + cash_value
            total_cash_value[count] = round(total_cash_value[count], 4)  # 现金账户每天的持仓

            total_account_value[count] = total_stock_value[count] + total_cash_value[count]  # 总账户每天的持仓

        total_stock_value_list.append(total_stock_value[count])  # 股票账户每天的持仓组成一个list
        total_cash_value_list.append(total_cash_value[count])  # 现金账户每天的持仓组成一个list
        total_account_value_list.append(total_account_value[count])  # 总账户每天的持仓组成一个list

    for k in range(len(total_account_value_list) - 1):
        daily_return = (total_account_value_list[k + 1] - total_account_value_list[k]) / \
                       total_account_value_list[k]  # 每天的收益率
        daily_return = round(daily_return, 4)  # 保留四位小数
        daily_return_list.append(daily_return)  # 每天的收益率list

        cum_return = (total_account_value_list[k + 1] - total_account_value_list[0]) / total_account_value_list[
            0]  # 累计收益率
        cum_return = round(cum_return, 4)  # 保留四位小数
        cum_return_list.append(cum_return)  # 累积收益率list

    ##处理上证指数
    st = get_stock()
    sh_index = st.get_a_stock("sh.000001", start, end)
    close_price_list = list(sh_index["close"])
    index_daily_return_list = [0]
    index_cum_return_list = [0]

    for i in range(len(close_price_list)):
        close_price_list[i] = float(close_price_list[i])

    for i in range(len(close_price_list) - 1):
        index_daily_return = (close_price_list[i + 1] - close_price_list[i]) / int(close_price_list[i])
        index_daily_return = round(index_daily_return, 4)
        index_daily_return_list.append(index_daily_return)  # 每天的指数收益率list
        # print(index_daily_return_list)

        index_cum_return = (close_price_list[i + 1] - close_price_list[0]) / close_price_list[0]
        index_cum_return = round(index_cum_return, 4)
        index_cum_return_list.append(index_cum_return)  # 每天的指数累积收益率list
        # print(index_cum_return_list)

    account_df = pd.DataFrame({"总账户价值": total_account_value_list,
                               "股票账户价值": total_stock_value_list,
                               "现金账户价值": total_cash_value_list,
                               "每日收益率": daily_return_list,
                               "累积收益率": cum_return_list,
                               "指数每日收益率": index_daily_return_list,
                               "指数累积收益率": index_cum_return_list
                               })

    account_df.index = ["%s" % x for x in tradeday] # 各账户的dataframe

    print(account_df)
    account_df.to_csv('./trade_log.csv')
    print('回测数据已保存到trade_log.csv')

    ploter().plot_performance(account_df)

    ##########日志类（总策略）

    total_return = (total_account_value_list[-1] - total_account_value_list[0]) / total_account_value_list[0]
    total_return = round(total_return, 4)
    print("策略总收益率:" + str(total_return))
    # 策略总收益率
    yearly_return = pow(1 + total_return, 1.0 / 10) - 1
    yearly_return = round(yearly_return, 4)
    print("策略年化收益率：" + str(yearly_return))  # 策略年化收益率

    index_j = np.argmax(np.maximum.accumulate(total_account_value_list) - total_account_value_list)  # 结束位置
    index_i = np.argmax(total_account_value_list[:index_j])  # 开始位置
    drawdown = (total_account_value_list[index_j] - total_account_value_list[index_i]) / \
               total_account_value_list[index_i]
    drawdown = round(drawdown, 4)
    print("最大回撤率：" + str(abs(drawdown)))
    # 最大回撤率

    index_j = np.argmax(np.maximum.accumulate(close_price_list) - close_price_list)  # 结束位置
    index_i = np.argmax(close_price_list[:index_j])  # 开始位置
    index_drawdown = (close_price_list[index_j] - close_price_list[index_i]) / close_price_list[index_i]
    index_drawdown = round(index_drawdown, 4)
    print("指数最大回撤率：" + str(abs(index_drawdown)))
    # 指数最大回撤率

    # print(daily_return_list)
    risk_premium = yearly_return - 0.0036  # 夏普比率的分子 风险溢价
    theMean = np.mean(daily_return_list)
    total = 0
    for item in daily_return_list:
        difference = item - theMean
        diffSq = difference ** 2
        total += diffSq
    sDev = (math.sqrt(total / len(daily_return_list))) / math.sqrt(10)  # 年化标准差
    # print(sDev)
    sharpe_ratio = risk_premium / sDev
    sharpe_ratio = round(sharpe_ratio, 4)
    print("夏普比率：" + str(sharpe_ratio))
    # 夏普比率

    index_total_return = (close_price_list[-1] - close_price_list[0]) / close_price_list[0]
    index_total_return = round(index_total_return, 4)
    index_yearly_return = pow(1 + index_total_return, 1.0 / 10) - 1
    risk_premium = index_yearly_return - 0.0036  # 夏普比率的分子 风险溢价
    theMean = np.mean(index_daily_return_list)
    total = 0
    for item in index_daily_return_list:
        difference = item - theMean
        diffSq = difference ** 2
        total += diffSq
    sDev = (math.sqrt(total / len(index_daily_return_list))) / math.sqrt(10)  # 年化标准差
    # print(sDev)
    sharpe_ratio = risk_premium / sDev
    sharpe_ratio = round(sharpe_ratio, 4)
    print("指数夏普比率：" + str(sharpe_ratio))  # 指数夏普比率
